#include "BitmapLoader.h"

Bitmap::Bitmap()
{
	BPP=0;
	width=0;
	height=0;
	bitmap_Image=NULL;
	size=0;
	bps=0;
	KompressionFormat=0;
}

Bitmap::Bitmap(int height, int width):BPP(0),width(width),height(height),bitmap_Image(0),
size(3*width*height+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)),bps(0),KompressionFormat(0)
{
	FileHeader.bfType = BI_RGB;
	FileHeader.bfSize = 2+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+size;
    FileHeader.bfReserved = 0; 
    FileHeader.bfOffBits = 2+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    InfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    InfoHeader.biWidth = width;
    InfoHeader.biHeight = height;
    InfoHeader.biPlanes = 1;
    InfoHeader.biBitCount = 24; // 24 bits/pixel
    InfoHeader.biCompression = 0; // Zero is the defaut Bitmap
    InfoHeader.biSizeImage = size;
    InfoHeader.biXPelsPerMeter = 2835; // 72 pixels/inch = 2834.64567 pixels per meter
    InfoHeader.biYPelsPerMeter = 2835;
    InfoHeader.biClrUsed = 0;
    InfoHeader.biClrImportant = 0;
}

Bitmap::Bitmap(const Bitmap& src)
{
	FileHeader = src.FileHeader;
	InfoHeader = src.InfoHeader;
	height = src.height;
	width = src.width;
	BPP= src.BPP;
	bitmap_Image=NULL;
	size=src.size;
	bps=src.bps;
	KompressionFormat=src.KompressionFormat;
}

Bitmap::~Bitmap()
{
	BPP=NULL;
	width=NULL;
	height=NULL;
	KompressionFormat=NULL;
	size=NULL;
	bps=NULL;
	delete[] bitmap_Image;
}
 
void *Bitmap::LoadBitmap(const char *Filename)
{
 FILE *File=NULL;
 unsigned int ImageIdx=0;
 //unsigned char *bitmap_Image=NULL;
 
 if(!Filename)
 {
	return false;
 }
 else
 {
	File=fopen(Filename,"rb");
	if(!File)
	{
	 return 0;
	}
 }

  fread(&FileHeader,sizeof(BITMAPFILEHEADER),1,File);
 if(ferror(File))
 {
	fclose(File);
	return 0;
 }
 

  fread(&InfoHeader,sizeof(BITMAPINFOHEADER),1,File);
 if(ferror(File))
 {
	fclose(File);
	return 0;
 }
 
 fseek(File,FileHeader.bfOffBits,SEEK_SET);
 if(ferror(File))
 {
	fclose(File);
	return 0;
 }

 if(InfoHeader.biSizeImage != 0)
 {
	 bitmap_Image=new unsigned char[InfoHeader.biSizeImage];
	 fread(bitmap_Image,InfoHeader.biSizeImage,1,File);
 }

 if(FileHeader.bfType != 0x4D42)
 {
	fclose(File);
 }

  if(!bitmap_Image)
 {
	free(bitmap_Image);
	fclose(File);
 }

 if(bitmap_Image==NULL)
 {
	fclose(File);
 }
 
  switch(InfoHeader.biCompression)
  {
  case BI_RGB:
	  height = InfoHeader.biHeight;
	  width = InfoHeader.biWidth;
	   break;
 
  case BI_RLE4:
	   Load8BitKompression(Filename);
	   break;
 
  case BI_RLE8:
	   Load24BitKompression(Filename);
	   break;
 
  default:
	  printf(";_;\n");
  }
 fclose(File);
 return (void*)bitmap_Image;
};
 
void Bitmap::Load8BitKompression(const char *Filename)
{
	Bitmap o_Bitmap;
	FILE *File=NULL;
	File=fopen(Filename,"rb");
    fread(&o_Bitmap.FileHeader,sizeof(BITMAPFILEHEADER),1,File);
	fread(&o_Bitmap.InfoHeader,sizeof(BITMAPINFOHEADER),1,File);

	if(FileHeader.bfType != 8)
	{
		fclose(File);
	}

	BPP=o_Bitmap.InfoHeader.biBitCount; 
	width=o_Bitmap.InfoHeader.biHeight;
	height=o_Bitmap.InfoHeader.biHeight;
	//KompressionFormat=GL_RGB;

	if(InfoHeader.biSizeImage != 0)
	{
		bitmap_Image=new unsigned char[o_Bitmap.InfoHeader.biSizeImage];
		fread(bitmap_Image,o_Bitmap.InfoHeader.biSizeImage,1,File);
	}
	
};
 
void Bitmap::Load24BitKompression(const char *Filename)
{
	Bitmap o_Bitmap;
	FILE *File=NULL;
	File=fopen(Filename,"rb");
    fread(&o_Bitmap.FileHeader,sizeof(BITMAPFILEHEADER),1,File);
	fread(&o_Bitmap.InfoHeader,sizeof(BITMAPINFOHEADER),1,File);

	if(o_Bitmap.FileHeader.bfType != 24)
	{
		fclose(File);
	}

	BPP=o_Bitmap.InfoHeader.biBitCount; 
	width=o_Bitmap.InfoHeader.biHeight;
	height=o_Bitmap.InfoHeader.biHeight;
	//KompressionFormat=GL_COLOR_INDEX;
};

void Bitmap::flush(const char*fileName)
{
	FILE *f = 0;
	fopen_s(&f, fileName,"wb");
	if (f == 0)
		return;
	fwrite((void*)&FileHeader, sizeof(BITMAPFILEHEADER), 1, f);
	fwrite((void*)&InfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
	fwrite(bitmap_Image, InfoHeader.biSizeImage, 1, f);
	fclose(f);
}